home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / EGAVGA.SWG / 0019_MODE-XY2.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  6KB  |  177 lines

  1. {
  2. Kai Rohrbacher
  3.  
  4. >> Basically,  Mode  Y  works  like  this:  use  the BIOS to switch
  5. >> into normal 320x200x256  mode,  then reprogram the sequencer to
  6. >> unchain the 4 bitplanes. This  results  in  a bitplaned VRAM layout
  7. >> very similiar to the EGA/VGA's 16 color modes:
  8. >
  9. > By saying 4 bitplanes, are you referering to the pages? I know that
  10. > you can specify 4 pages in mode X/Y.
  11.  
  12. No, it just means that with each VRAM address, 4 physically different RAM cells
  13. can be addressed: you may think of a "3-dimensional" architecture of your VGA's
  14. VRAM (ASCII sucks, I know...)
  15.              ____________
  16.             |*  plane3   |
  17.          ___|_________   |
  18.         |*   plane2   |__|
  19.      ___|__________   |
  20.     |*   plane1    |__|
  21.  ___|___________   |
  22. |*   plane0     |__|
  23. |               |
  24. |_______________|
  25.  
  26. The upper left corner of each bitplane (marked by a "*") is referenced with the
  27. address $A000:0, but refers to 4 pixels! It is quite simple: instead of
  28. counting "$A000:0 is the first pixel, $A000:1 is the 2nd, $A000:2 is the 3rd,
  29. $A000:3 is the 4th, $A000:4 is the 5th" (as you would do in the normal BIOS
  30. mode 320x200x256), the pixels now are distributed this way: "$A000:0/plane 0 is
  31. the 1st, $A000:0/plane 1 is the 2nd, $A000:0/plane 2 is the 3rd, $A000:0/plane
  32. 3 is the 4th, $A000:1/plane 0 is the 5th" and so on.
  33. So obviously, w/o doing some "bitplane switching", you are always restricted to
  34. work on one bitplane at a time --the one actually being activated. If this is
  35. plane0, you may only change pixels which (x mod 4) remainder is 0, the other
  36. ones with (x mod 4)=1|2|3 aren't accessible, you have to "switch to the plane"
  37. first. Thus the name "bitplane"!
  38.  
  39. DT> And what exactly does "unchain" mean, as opposed to "chained". I have the
  40. DT> feeling that they refer to each page(bitplane) being on its own.
  41. Huhh, that would go pretty much into details; a bit simplified, "chained" means
  42. that the bitplanes mentioned above are "glued" together for the simple BIOS
  43. mode, so that bitplane switching isn't necessary anymore (that is equivalent in
  44. saying that one VRAM address refers to one RAM cell). As there are only 65536
  45. addresses in the $A000 segment and we need 320x200=64000 for a full page, you
  46. only have 65536/64000=1.024 pages therefore. "Unchaining" means to make each
  47. bitplane accessible explicitely.
  48.  
  49. > Now here is another problem I don't understand. I am familiar with VGA's
  50. > mode 13h which has one byte specifying each pixel on the screen,
  51. > therefore 1 byte = 1 pixel. But this takes up 64k.
  52.  
  53. Small note on this: not 64K, but only 64000 bytes!
  54.  
  55. > But how do you have one address represent 4 pixels, which only occupies
  56. > 16000 address bytes, and still be able to specify 256 colours. Won't 4
  57. > bitplanes at 320x200 each take up 64000x4 bytes of space?
  58.  
  59. We have 320x200=64000 pixels=64000 bytes. As each 4 pixels share one address,
  60. 16000 address bytes per page suffice. The $A000 segment has 64K address bytes,
  61. thus 4*64K=256K VRAM can be addressed. 64K address bytes = 65536 address bytes;
  62. 65536/16000 = 4.096 pages.
  63.  
  64. > How would you go about adjusting the vertical retraces, and memory
  65. > location you mentioned.
  66.  
  67. Assuming that the DX-register has been set to 3DAh or 3BAh for color/monochrome
  68. display, respectively, you can trace the status of the electronic beam like
  69. this:
  70.  
  71.   @WaitNotVSyncLoop:
  72.     in   al, dx
  73.     and  al, 8
  74.     jnz  @WaitNotVSyncLoop
  75.   @WaitVSyncLoop:
  76.     in   al, dx
  77.     and  al, 8
  78.     jz   @WaitVSyncLoop
  79.   {now change the starting address}
  80. {
  81. (If you use "1" instead of "8" and exchange "jz" <-> "jnz" and vice vs., then
  82. you sync on the shorter horizontal retrace (better: horizontal _enable_)
  83. signal).
  84. The alteration of the starting address is done by the code I already posted in
  85. my first mail! (Its done by addressing the registers $C and $D of the
  86. CRT-controller).
  87. Note that reprogramming the starting address isn't restricted to mode X/Y, you
  88. can have it in normal mode 13h, too: there are 65536 addresses available, but
  89. only 64000 needed, thus giving a scroll range of 4.8 lines! And to complicate
  90. things even further, for start addressing purposes, even the BIOS mode is
  91. planed (that is, a row consists of 320/4 bytes only). Just for the case you
  92. don't believe...
  93. }
  94. PROGRAM Scroll;
  95. VAR
  96.   CRTAddress,
  97.   StatusReg   : WORD;
  98.   a           : ARRAY[0..199, 0..319] OF BYTE ABSOLUTE $A000 : 0000;
  99.   i, j        : WORD;
  100.  
  101. PROCEDURE SetAddress(ad : WORD); ASSEMBLER;
  102. ASM
  103.   MOV BX, ad
  104.  
  105.   MOV DX, StatusReg
  106.   @WaitNotVSyncLoop:
  107.     in   al, dx
  108.     and  al, 8
  109.     jnz  @WaitNotVSyncLoop
  110.   @WaitVSyncLoop:
  111.     in   al, dx
  112.     and  al, 8
  113.     jz   @WaitVSyncLoop
  114.  
  115.   MOV DX, CRTAddress
  116.   MOV AL, $0D
  117.   CLI
  118.   OUT DX, AL
  119.   INC DX
  120.   MOV AL, BL
  121.   OUT DX, AL
  122.   DEC DX
  123.   MOV AL, $0C
  124.   OUT DX, AL
  125.   INC DX
  126.   MOV AL, BH
  127.   OUT DX, AL
  128.   STI
  129. END;
  130.  
  131. BEGIN
  132.   IF ODD(port[$3CC]) THEN
  133.     CRTAddress := $3D4
  134.   ELSE
  135.     CRTAddress := $3B4;
  136.  
  137.   StatusReg := CRTAddress + 6;
  138.   ASM
  139.     MOV AX,13h
  140.     INT 10h
  141.   END;
  142.  
  143.   FOR i := 1 TO 1000 DO
  144.    a[Random(200), Random(320)] := Random(256);
  145.  
  146.   {scroll horizontally by 4 pixels}
  147.   FOR i := 1 TO 383 DO
  148.     SetAddress(i);
  149.   FOR i := 382 DOWNTO 0 DO
  150.     SetAddress(i);
  151.  
  152.   {scroll vertically by 1 row}
  153.   FOR j := 1 TO 20 DO
  154.   BEGIN
  155.     FOR i := 1 TO 4 DO
  156.       SetAddress(i * 80);
  157.     FOR i := 3 DOWNTO 0 DO
  158.       SetAddress(i * 80)
  159.   END;
  160.  
  161.   ASM {back to 80x25}
  162.     MOV AX,3
  163.     INT 10h
  164.   END;
  165.  
  166. END.
  167. {
  168. > Your said you could specify how the memory can be layed out by the user,
  169. > but I am in need of what each PORT does. I know you have to send
  170. > different values to the port to program it, but I have no idea what each
  171. > port reads.
  172.  
  173. There are incredibly much registers to program! For a good overview of most of
  174. them, try to get your hands on a copy of VGADOC*.* by Finn Thoegersen
  175. (jesperf@daimi.aau.dk) which covers programming a lot of SVGA's chipsets, too.
  176.  
  177.